package org.ceva.training.controller;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;
import org.ceva.training.persistence.bo.Course;
import org.ceva.training.persistence.bo.TrainingDetails;
import org.ceva.training.persistence.bo.User;
import org.ceva.training.persistence.dao.CourseDAO;
import org.ceva.training.persistence.dao.UsersDAO;
import org.ceva.training.service.TrainingDetailService;
import org.ceva.training.ui.renderer.SelectListBoxRenderer;
import org.zkoss.calendar.Calendars;
import org.zkoss.calendar.api.CalendarEvent;
import org.zkoss.calendar.event.CalendarsEvent;
import org.zkoss.calendar.impl.SimpleCalendarModel;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.TrainingSchedule;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.ForwardEvent;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zkplus.spring.SpringUtil;
import org.zkoss.zul.Datebox;
import org.zkoss.zul.Div;
import org.zkoss.zul.ListModel;
import org.zkoss.zul.Listbox;
import org.zkoss.zul.Listitem;
import org.zkoss.zul.SimpleListModel;
import org.zkoss.zul.Textbox;
import org.zkoss.zul.Timebox;
import org.zkoss.zul.Window;

public class ScheduleWindow extends GenericForwardComposer {

	private static final String TB_TEXT = "tbText";
	private static final String USER_LIST_BOX = "userListBox";
	private static final String END_TIME = "endTime";
	private static final String BEGIN_TIME = "beginTime";
	private static final String END_DATE = "endDate";
	private static final String BEGIN_DATE = "beginDate";
	private static final String COURSE_LIST_BOX = "courseListBox";
	private static Logger log = Logger.getLogger(ScheduleWindow.class);
	Div calDiv;
	Calendars cal;
	Window creationDialog = null;

	public void createSchedule(CalendarsEvent evt) {
		cal.setVisible(false);
		if (creationDialog == null)
			creationDialog = (Window) Executions.createComponents(
					"createEntry.zul", calDiv, null);
		creationDialog.setVariable("calevent", evt, false);
		((Datebox) creationDialog.getFellow(BEGIN_DATE)).setValue(evt
				.getBeginDate());
		((Datebox) creationDialog.getFellow(END_DATE)).setValue(evt
				.getEndDate());
		creationDialog.setVariable("scheduleComposer", this, false);

		((Timebox) creationDialog.getFellow(BEGIN_TIME)).setValue(evt
				.getBeginDate());
		((Timebox) creationDialog.getFellow(END_TIME)).setValue(evt
				.getEndDate());

		Listbox userBox = (Listbox) creationDialog.getFellow(USER_LIST_BOX);
		userBox.setItemRenderer(new SelectListBoxRenderer<User>(null,null));
		userBox.setModel(getUsers());
		
		Listbox courseBox = (Listbox) creationDialog.getFellow(COURSE_LIST_BOX);
		courseBox.setItemRenderer(new SelectListBoxRenderer<Course>(null,null));
		courseBox.setModel(getCourses());
		creationDialog.setVisible(true);

	}

	public void editSchedule(CalendarsEvent evt) {
		cal.setVisible(false);
		TrainingSchedule schedule = (TrainingSchedule) evt.getCalendarEvent();
		if (creationDialog == null)
			creationDialog = (Window) Executions.createComponents(
					"createEntry.zul", calDiv, null);
		((Datebox) creationDialog.getFellow(BEGIN_DATE)).setValue(schedule
				.getBeginDate());
		((Datebox) creationDialog.getFellow(END_DATE)).setValue(schedule
				.getEndDate());
		((Timebox) creationDialog.getFellow(BEGIN_TIME)).setValue(schedule
				.getBeginDate());
		((Timebox) creationDialog.getFellow(END_TIME)).setValue(schedule
				.getEndDate());
		((Textbox) creationDialog.getFellow(TB_TEXT)).setText(schedule
				.getData().getTrainingDescription());

		Listbox userBox = (Listbox) creationDialog.getFellow(USER_LIST_BOX);
		userBox.setItemRenderer(new SelectListBoxRenderer<User>(schedule.getData().getTrainees(),
				new Comparator<User>(){
					public int compare(User o1, User o2) {
						if(o1.getUserid().equals(o2.getUserid()))
						return 0;
						else
						return 1;
					}
			}
		));
		userBox.setModel(getUsers());
		
		Listbox courseBox = (Listbox)creationDialog.getFellow(COURSE_LIST_BOX);
		List<Course> courses = new ArrayList<Course>();
		courses.add(schedule.getData().getCourse());
		courseBox.setItemRenderer(new SelectListBoxRenderer<Course>(courses,
				new Comparator<Course>() {
					public int compare(Course o1, Course o2) {
						return o1.getCourseid() == o2.getCourseid() ? 0 : -1;
					}
				}));
		courseBox.setModel(getCourses());
		creationDialog.setVariable("scheduleComposer", this, false);
		creationDialog.setVariable("editTrainingDetails", schedule, false);
		creationDialog.setVisible(true);

	}

	public void onClickbtnAdd() {

		Date beginDate = ((Datebox) creationDialog.getFellow(BEGIN_DATE))
				.getValue();
		Date endDate = ((Datebox) creationDialog.getFellow(END_DATE))
				.getValue();
		String scheduleDescription = ((Textbox) creationDialog
				.getFellow(TB_TEXT)).getText();
		Listbox userBox = (Listbox) creationDialog.getFellow(USER_LIST_BOX);
		Set<Listitem> selectedUsers = userBox.getSelectedItems();
		List<User> users = new ArrayList<User>();
		for (Listitem listitem : selectedUsers) {
			users.add((User) listitem.getValue());
		}
		
		Listbox courseBox = (Listbox)creationDialog.getFellow(COURSE_LIST_BOX);
		Course selectedCourse = courseBox.getSelectedItem()!=null ?(Course)courseBox.getSelectedItem().getValue():null;
		
		TrainingSchedule schedule = (TrainingSchedule) creationDialog
				.getVariable("editTrainingDetails", false);
		TrainingDetails details = null;
		if (schedule == null) {
			details = new TrainingDetails(users, null, scheduleDescription,
					beginDate, endDate,selectedCourse);
		} else {
			details = schedule.getData();
			details.setStartDate(beginDate);
			details.setEndDate(endDate);
			details.setTrainees(users);
			details.setTrainingDescription(scheduleDescription);
			details.setCourse(selectedCourse);
		}
		TrainingDetailService service = (TrainingDetailService) SpringUtil
				.getBean("trainingDetailService");
		service.save(details);
		log.info("Saved Training " + details.getTrainingDescription()
				+ " in DB with id " + details.getScheduleId());
		if (schedule == null) {
			schedule = new TrainingSchedule(details, false);
			((SimpleCalendarModel) cal.getModel()).add(schedule);
		}
		cal.setVisible(true);
		creationDialog.setVisible(false);
	}

	public ListModel getUsers() {

		ListModel model = null;
		UsersDAO dao = (UsersDAO) SpringUtil.getBean("UsersDAO");
		List<User> users = dao.findByUserRole("trainee");
		if (users != null && users.size() > 0) {
			model = new SimpleListModel(users);
		}
		return model;
	}
	
	public ListModel getCourses(){
		ListModel model =null;
		CourseDAO dao = (CourseDAO)SpringUtil.getBean("CourseDAO");
		List<Course> courses= dao.findAll();
		if (courses != null) {
			model = new SimpleListModel(courses);
		}
		return model;
	}

	public SimpleCalendarModel getModel() {
		SimpleCalendarModel model = new SimpleCalendarModel();
		TrainingDetailService service = (TrainingDetailService) SpringUtil
				.getBean("trainingDetailService");
		List<TrainingDetails> trainings = service.getAll();
		for (TrainingDetails trainingDetails : trainings) {
			TrainingSchedule schedule = new TrainingSchedule(trainingDetails,
					false);
			model.add(schedule);
		}
		return model;
	}

}
